package org.example.demo1.service;

import lombok.extern.slf4j.Slf4j;
import org.example.demo1.ai.ChatRedisMemory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.messages.*;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AiAgentService {

    private final ChatClient toolClient;
    private final ChatRedisMemory chatMemory;

    private final RedisTemplate<String, Object> redisTemplate;

    private static final String SESSION_KEY_PREFIX = "session:info:";
    private static final String SESSION_LIST_KEY = "session:list";
    private static final int SESSION_EXPIRE_DAYS = 7;

    @Autowired
    ChatRedisMemory chatRedisMemory;

    private final String SYSTEM_PROMPT = """
            你是一个顶级的K8s运维专家机器人。你的任务是诊断并解决用户提出的K8s集群问题。
            你必须遵循"思考 -> 行动"的模式来解决问题。
                        
            重要提示：
            - 如果工具调用失败或超时，请告知用户具体的错误信息，并提供排查建议
            - 首先使用 checkClusterHealth 检查集群连接状态
            - 如果连接正常，再使用 getPodStatus 获取Pod状态
            - 根据结果提供专业的K8s故障排查建议
                        
            1. **分析**: 基于当前的用户问题和历史信息，分析情况。
            2. **决策**:
               - 如果缺少信息，你必须调用一个或多个你可用的工具来获取信息
               - 如果工具调用失败，提供基于错误信息的排查建议
               - 如果你已经掌握了所有信息并能回答用户的问题，就向用户提供最终的、详细的答案
            """;


    @Autowired
    public AiAgentService(ChatClient toolClient, ChatRedisMemory chatMemory, RedisTemplate<String, Object> redisTemplate) {
        this.toolClient = toolClient;
        this.chatMemory = chatMemory;
        this.redisTemplate = redisTemplate;
    }


    public String processCommand(String command, String sessionId) {
        if (command == null || command.trim().isEmpty()) {
            return "错误：输入不能为空";
        }
        log.info("🤖 处理AI指令: {} (Session: {})", command, sessionId);

        List<Message> conversationHistory = new ArrayList<>();

        // 使用更详细的系统提示
        SystemMessage systemMessage = new SystemMessage(SYSTEM_PROMPT);
        conversationHistory.add(systemMessage);
        conversationHistory.add(new UserMessage(command));

        //构建一个prompt
        Prompt prompt = new Prompt(conversationHistory);

        ChatResponse response = toolClient.prompt(prompt).advisors(new MessageChatMemoryAdvisor(chatRedisMemory, sessionId, 10)).call().chatResponse();

        AssistantMessage assistantMessage = response.getResult().getOutput();

        String finalAnswer = getMessageContent(assistantMessage);

        return finalAnswer;
    }

    // 创建新会话
    public String createNewSession(String title) {
        String sessionId = generateSessionId();

        Map<String, Object> sessionInfo = new HashMap<>();
        sessionInfo.put("sessionId", sessionId);
        sessionInfo.put("title", title);
        sessionInfo.put("createdAt", LocalDateTime.now().toString());
        sessionInfo.put("lastUpdated", LocalDateTime.now().toString());
        sessionInfo.put("messageCount", 0);

        // 保存会话信息
        String sessionKey = SESSION_KEY_PREFIX + sessionId;
        redisTemplate.opsForHash().putAll(sessionKey, sessionInfo);
        redisTemplate.expire(sessionKey, SESSION_EXPIRE_DAYS, TimeUnit.DAYS);

        // 添加到会话列表
        redisTemplate.opsForZSet().add(SESSION_LIST_KEY, sessionId, System.currentTimeMillis());

        log.info("🆕 创建新会话: {} - {}", sessionId, title);
        return sessionId;
    }

    // 获取所有会话
    public List<Map<String, Object>> getAllSessions() {
        try {
            // 从有序集合中获取所有会话ID（按时间倒序）
            Set<Object> sessionIds = redisTemplate.opsForZSet().reverseRange(SESSION_LIST_KEY, 0, -1);

            List<Map<String, Object>> sessions = new ArrayList<>();

            if (sessionIds != null) {
                for (Object sessionIdObj : sessionIds) {
                    String sessionId = sessionIdObj.toString();
                    String sessionKey = SESSION_KEY_PREFIX + sessionId;

                    // 检查会话是否存在
                    if (redisTemplate.hasKey(sessionKey)) {
                        Map<Object, Object> sessionInfo = redisTemplate.opsForHash().entries(sessionKey);

                        if (!sessionInfo.isEmpty()) {
                            Map<String, Object> session = new HashMap<>();
                            sessionInfo.forEach((k, v) -> session.put(k.toString(), v));
                            sessions.add(session);
                        }
                    } else {
                        // 如果会话信息不存在，从列表中移除
                        redisTemplate.opsForZSet().remove(SESSION_LIST_KEY, sessionId);
                    }
                }
            }

            log.info("📋 获取到 {} 个会话", sessions.size());
            return sessions;
        } catch (Exception e) {
            log.error("获取会话列表失败: {}", e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    // 获取会话消息
    public List<Map<String, Object>> getSessionMessages(String sessionId) {
        try {
            var messages = chatMemory.get(sessionId, 50); // 获取最近50条消息

            List<Map<String, Object>> messageList = new ArrayList<>();
            for (var message : messages) {
                Map<String, Object> msg = new HashMap<>();
                msg.put("type", message.getMessageType().getValue());
                msg.put("text", message.getText());
                msg.put("timestamp", System.currentTimeMillis()); // 可以考虑在ChatEntity中添加timestamp字段
                messageList.add(msg);
            }

            log.info("📨 获取会话 {} 的 {} 条消息", sessionId, messageList.size());
            return messageList;
        } catch (Exception e) {
            log.error("获取会话消息失败: {}", e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    // 删除会话
    public boolean deleteSession(String sessionId) {
        try {
            String sessionKey = SESSION_KEY_PREFIX + sessionId;

            // 删除会话信息
            Boolean sessionDeleted = redisTemplate.delete(sessionKey);

            // 从会话列表中移除
            Long listRemoved = redisTemplate.opsForZSet().remove(SESSION_LIST_KEY, sessionId);

            // 清除聊天记忆
            chatMemory.clear(sessionId);

            boolean success = (sessionDeleted != null && sessionDeleted) || (listRemoved != null && listRemoved > 0);

            if (success) {
                log.info("🗑️ 成功删除会话: {}", sessionId);
            } else {
                log.warn("⚠️ 会话 {} 可能不存在或已被删除", sessionId);
            }

            return success;
        } catch (Exception e) {
            log.error("删除会话失败: {}", e.getMessage(), e);
            return false;
        }
    }

    // 更新会话标题
    public boolean updateSessionTitle(String sessionId, String title) {
        try {
            String sessionKey = SESSION_KEY_PREFIX + sessionId;

            if (!redisTemplate.hasKey(sessionKey)) {
                return false;
            }

            redisTemplate.opsForHash().put(sessionKey, "title", title);
            redisTemplate.opsForHash().put(sessionKey, "lastUpdated", LocalDateTime.now().toString());

            log.info("✏️ 更新会话标题: {} -> {}", sessionId, title);
            return true;
        } catch (Exception e) {
            log.error("更新会话标题失败: {}", e.getMessage(), e);
            return false;
        }
    }

    // 清除指定会话的聊天记忆
    public void clearSession(String sessionId) {
        log.info("🗑️ 清除会话记忆: {}", sessionId);
        try {
            chatMemory.clear(sessionId);

            // 重置消息计数
            String sessionKey = SESSION_KEY_PREFIX + sessionId;
            if (redisTemplate.hasKey(sessionKey)) {
                redisTemplate.opsForHash().put(sessionKey, "messageCount", 0);
                redisTemplate.opsForHash().put(sessionKey, "lastUpdated", LocalDateTime.now().toString());
            }
        } catch (Exception e) {
            log.error("清除会话记忆时发生错误: {}", e.getMessage(), e);
            throw new RuntimeException("清除会话失败", e);
        }
    }

    // 批量删除过期会话
    public int cleanupExpiredSessions() {
        try {
            long cutoffTime = System.currentTimeMillis() - (SESSION_EXPIRE_DAYS * 24 * 60 * 60 * 1000L);

            // 获取过期的会话ID
            Set<Object> expiredSessions = redisTemplate.opsForZSet().rangeByScore(SESSION_LIST_KEY, 0, cutoffTime);

            int deletedCount = 0;
            if (expiredSessions != null && !expiredSessions.isEmpty()) {
                for (Object sessionIdObj : expiredSessions) {
                    String sessionId = sessionIdObj.toString();
                    if (deleteSession(sessionId)) {
                        deletedCount++;
                    }
                }
            }

            log.info("🧹 清理了 {} 个过期会话", deletedCount);
            return deletedCount;
        } catch (Exception e) {
            log.error("清理过期会话失败: {}", e.getMessage(), e);
            return 0;
        }
    }

    // 获取会话统计信息
    public Map<String, Object> getSessionStats() {
        Map<String, Object> stats = new HashMap<>();
        try {
            // 总会话数
            Long totalSessions = redisTemplate.opsForZSet().count(SESSION_LIST_KEY, 0, System.currentTimeMillis());
            stats.put("totalSessions", totalSessions != null ? totalSessions : 0);

            // 今天创建的会话数
            long todayStart = System.currentTimeMillis() - (24 * 60 * 60 * 1000L);
            Long todaySessions = redisTemplate.opsForZSet().count(SESSION_LIST_KEY, todayStart, System.currentTimeMillis());
            stats.put("todaySessions", todaySessions != null ? todaySessions : 0);

            // 活跃会话数（最近1小时有活动）
            long oneHourAgo = System.currentTimeMillis() - (60 * 60 * 1000L);
            Long activeSessions = redisTemplate.opsForZSet().count(SESSION_LIST_KEY, oneHourAgo, System.currentTimeMillis());
            stats.put("activeSessions", activeSessions != null ? activeSessions : 0);

            log.info("📊 会话统计: {}", stats);
        } catch (Exception e) {
            log.error("获取会话统计失败: {}", e.getMessage(), e);
            stats.put("error", e.getMessage());
        }
        return stats;
    }

    // 私有辅助方法
    private void updateSessionActivity(String sessionId) {
        try {
            // 更新会话在列表中的时间戳
            redisTemplate.opsForZSet().add(SESSION_LIST_KEY, sessionId, System.currentTimeMillis());

            // 更新会话信息的最后更新时间
            String sessionKey = SESSION_KEY_PREFIX + sessionId;
            if (redisTemplate.hasKey(sessionKey)) {
                redisTemplate.opsForHash().put(sessionKey, "lastUpdated", LocalDateTime.now().toString());
            } else {
                // 如果会话信息不存在，创建一个基本的会话信息
                createSessionInfoIfNotExists(sessionId);
            }
        } catch (Exception e) {
            log.error("更新会话活跃时间失败: {}", e.getMessage(), e);
        }
    }

    private void updateSessionAfterMessage(String sessionId, String userMessage) {
        try {
            String sessionKey = SESSION_KEY_PREFIX + sessionId;

            if (redisTemplate.hasKey(sessionKey)) {
                // 增加消息计数
                redisTemplate.opsForHash().increment(sessionKey, "messageCount", 1);

                // 如果标题还是默认的，尝试用第一条消息更新标题
                Object currentTitle = redisTemplate.opsForHash().get(sessionKey, "title");
                if (currentTitle == null || "新对话".equals(currentTitle.toString())) {
                    String newTitle = userMessage.length() > 20 ?
                            userMessage.substring(0, 20) + "..." : userMessage;
                    redisTemplate.opsForHash().put(sessionKey, "title", newTitle);
                }
            }
        } catch (Exception e) {
            log.error("更新会话消息信息失败: {}", e.getMessage(), e);
        }
    }

    private void createSessionInfoIfNotExists(String sessionId) {
        String sessionKey = SESSION_KEY_PREFIX + sessionId;

        if (!redisTemplate.hasKey(sessionKey)) {
            Map<String, Object> sessionInfo = new HashMap<>();
            sessionInfo.put("sessionId", sessionId);
            sessionInfo.put("title", "新对话");
            sessionInfo.put("createdAt", LocalDateTime.now().toString());
            sessionInfo.put("lastUpdated", LocalDateTime.now().toString());
            sessionInfo.put("messageCount", 0);

            redisTemplate.opsForHash().putAll(sessionKey, sessionInfo);
            redisTemplate.expire(sessionKey, SESSION_EXPIRE_DAYS, TimeUnit.DAYS);

            log.info("🆕 自动创建会话信息: {}", sessionId);
        }
    }

    private String generateSessionId() {
        return "session_" + System.currentTimeMillis() + "_" +
                UUID.randomUUID().toString().replace("-", "").substring(0, 8);
    }

    private String generateDefaultSessionId() {
        return "session_" + System.currentTimeMillis();
    }

    /**
     * 安全地获取消息内容
     */
    private String getMessageContent(Message message) {
        try {
            if (message instanceof UserMessage userMessage) {
                return userMessage.getText();
            } else if (message instanceof AssistantMessage assistantMessage) {
                return assistantMessage.getText();
            } else if (message instanceof SystemMessage systemMessage) {
                return systemMessage.getText();
            } else {
                return String.valueOf(message);
            }
        } catch (Exception e) {
            log.warn("获取消息内容时出错: {}", e.getMessage());
            return "[无法获取消息内容: " + e.getMessage() + "]";
        }
    }
}
